﻿using Blazored.SessionStorage;
using System.Net.Http.Json;
using WhutDoomCheck.Shared;
using WhutDoomCheck.Shared.HttpModels;

namespace WhutDoomCheck.Client.Services
{
    public class StudentClient
    {
        public StudentClient(HttpClient http, ISessionStorageService cache)
        { 
            this.http = http;
            this.cache = cache;
        }

        private readonly HttpClient http;
        private readonly ISessionStorageService cache;

        public async Task<bool> Login(string username, string password)
        {
            var resp = await http.PostAsJsonAsync("/api/login/student", new { username, password });

            if (resp.StatusCode == System.Net.HttpStatusCode.Unauthorized) return false;

            var result = await resp.Content.ReadFromJsonAsync<Token>();

            await cache.SetItemAsync("AccessToken", result!.AccessToken);
            return true;
        }

        public async Task<DoomMeta> GetDoomMeta()
        {
            var token = await cache.GetItemAsync<string>("AccessToken");

            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

            var result = await http.GetFromJsonAsync<DoomMeta>("/api/Meta/GetDooms")?? throw new InvalidCastException();
            return result;
        }

        public async Task<Bed?> GetBed()
        {
            var token = await cache.GetItemAsync<string>("AccessToken");

            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

            try
            {
                var result = await http.GetFromJsonAsync<Bed>("/api/Student/GetDoom");
                return result;
            }
            catch
            {
                // TODO 加一层Wrapper
                return null;
            }
        }

        
        public async Task<bool> UpdateDoom(UpdateDoomRequest request)
        {
            var token = await cache.GetItemAsync<string>("AccessToken");

            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

            var result = await http.PostAsJsonAsync("/api/Student/UpdateDoom", request) ?? throw new InvalidCastException();
            
            return result.StatusCode == System.Net.HttpStatusCode.OK;
        }        
        
        public async Task<bool> UpdateHotel(UpdateHotelRequest request)
        {
            var token = await cache.GetItemAsync<string>("AccessToken");

            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

            var result = await http.PostAsJsonAsync("/api/Student/UpdateHotel", request) ?? throw new InvalidCastException();
            
            return result.StatusCode == System.Net.HttpStatusCode.OK;
        }

        public async Task<Profile> GetProfile()
        {
            var token = await cache.GetItemAsync<string>("AccessToken");

            http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

            var result = await http.GetFromJsonAsync<Profile>("/api/Student/GetProfile") ?? throw new InvalidCastException();

            return result;
        }

        public async Task<IList<CNRegion>> GetProvinces()
        {
            var result = await http.GetFromJsonAsync<IList<CNRegion>>("/api/Meta/GetProvinces") ?? throw new InvalidCastException();
            return result;
        }

        public async Task<IList<CNRegion>> GetRegionChildren(long parent)
        {
            var result = await http.GetFromJsonAsync<IList<CNRegion>>($"/api/Meta/GetChildren?parent={parent}") ?? throw new InvalidCastException();
            return result;
        }
    }
}
